package it.bit.jlightqueryer.gui;

import it.bit.jlightqueryer.bl.Engine;
import it.bit.jlightqueryer.bl.U;
import it.bit.jlightqueryer.conn.Connection;
import it.bit.jlightqueryer.conn.Driver;
import it.bit.jlightqueryer.conn.Drivers;
import it.bit.jlightqueryer.conn.Recents;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.DefaultListSelectionModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.text.Document;

/**
 * Visual class to handle initial connection choose.<br>
 * Hey, this class is more complicate than FrMain! :)
 * @author PerezDeQueya80
 */
public class MainChooser extends JFrame {

	private static final long serialVersionUID = 1L;
	private Recents recents;
	private List connections = new ArrayList();

	private JPanel jContentPane = null;
	private JLabel lblImage = null;
	private JPanel panConnection = null;
	private JPanel panRecent = null;
	private JComboBox cmbDriver = null;
	private JPanel panVariales = null;
	private JPanel panConstants = null;
	private JLabel lblUser = null;
	private JTextField txtUser = null;
	private JLabel lblPassword = null;
	private JPasswordField txtPassword = null;
	private JLabel lblURL = null;
	private JLabel lblRecent = null;
	private JScrollPane spnRecent = null;
	private DefaultListSelectionModel listSelectionModelRecent = null;  //  @jve:decl-index=0:visual-constraint="755,17"
	private JButton btnConnect = null;
	private JTable tableRecent = null;
	private JButton btnAdd = null;
	private JCheckBox chkSavePassword = null;

	/**
	 * This is the default constructor
	 */
	public MainChooser() {
		super();
		initialize();

		loadDriverCombo();
		loadRecents();
		U.adjustColumns(getTableRecent());
		newC();
	}

	private void loadDriverCombo() {
		Driver[] drivers = Drivers.getDrivers();
		for (int i = 0; i < drivers.length; i++) {
			getCmbDriver().addItem(drivers[i]);
		}
		if (getCmbDriver().getItemCount()>0) getCmbDriver().setSelectedIndex(0);
	}

	private void loadRecents() {
		try {
			recents = new Recents();
			int count = recents.getCount();
			for (int i = 0; i < count; i++) {
				connections.add(new Connection(recents,i));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private int getRecentRow(int row) {
//		return row; // if you want normal order
		return connections.size()-row-1;
	}

	private int getSelectedRecentRow() {
		int row = getTableRecent().getSelectedRow();
		if (row>-1) {
			return getRecentRow(row);
		}
		else {
			return row;
		}
	}

	private Connection getConnection(int row) {
		return (Connection) connections.get(row);
	}

	private void selectC() {
		int row = getSelectedRecentRow();
		if (row>-1) {
			Connection conn = getConnection(row);
			upload(conn);
		}
		else {
			if (getCmbDriver().getItemCount()>0) getCmbDriver().setSelectedIndex(0);
		}
	}

	private void newC() {
		getTableRecent().clearSelection();
//		selectC();
	}

	private void connectC() {
		try {
			Connection connection = download();
			int row = getSelectedRecentRow();
			if (row>-1) {
				// reset connection values
				connection.setToRecents(recents, row);
				connections.set(row, connection);
			}
			else {
				connection.addToRecents(recents);
				connections.add(connections);
			}
			Engine.setConnection(connection);
			dispose();
			FrMain fr = new FrMain(); // @jve:decl-index=0:
			fr.setVisible(true);
		}
		catch (Exception e) {
			String stacktrace = U.stack2string(e);
			JOptionPane.showConfirmDialog(this, new Object[]{
					e.getMessage()
					, new JScrollPane(new JTextArea(stacktrace))
				}
			, "Errore", JOptionPane.ERROR_MESSAGE);
		}
	}

	private void upload(Driver driver) {
		getCmbDriver().setSelectedItem(driver);
		GridBagConstraints constrLbl = new GridBagConstraints(0,-1,1,1,0.0,0.0,GridBagConstraints.EAST,GridBagConstraints.NONE,new Insets(2,2,2,2),0,0);
		GridBagConstraints constrTxt = new GridBagConstraints(1,-1,1,1,1.0,0.0,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(2,2,2,2),0,0);
		getPanVariales().removeAll();
		String[] var = driver.getVariables();
		String[] def = driver.getDefaults();
		for (int i = 0; i < var.length; i++) {
			JLabel lbl = new JLabel(var[i]);
			JTextField txt = new JTextField(def[i]);
			Document txtDoc = txt.getDocument();
			txtDoc.addDocumentListener(new DocumentListener() {
				public void changedUpdate(DocumentEvent e) {
				}
				public void insertUpdate(DocumentEvent e) {
					refreshURL();
				}
				public void removeUpdate(DocumentEvent e) {
					refreshURL();
				}
			});
			GridBagConstraints constr = (GridBagConstraints) constrLbl.clone();
			constr.gridy = i;
			getPanVariales().add(lbl, constr);
			constr = (GridBagConstraints) constrTxt.clone();
			constr.gridy = i;
			getPanVariales().add(txt, constr);
		}
		Dimension d = getSize();
		setSize(d.width, d.height+1);
		setSize(d);
	}

	private void upload(Connection connection) {
		upload(connection.getDriver());
		String[] var = connection.getDriver().getVariables();
		String[] val = connection.getValues();
		for (int i = 0; i < var.length; i++) {
			JTextField txt = (JTextField) getPanVariales().getComponent((i*2)+1);
			txt.setText(val[i]);
		}
		getChkSavePassword().setSelected(connection.isSavePassword());
		getTxtUser().setText(connection.getUsername());
		getTxtPassword().setText(connection.getPassword());
	}

	private Connection download() {
		Driver driver = (Driver) getCmbDriver().getSelectedItem();
		String[] var = driver.getVariables();
		String[] val = new String[var.length];
		for (int i = 0; i < var.length; i++) {
			JTextField txt = (JTextField) getPanVariales().getComponent((i*2)+1);
			val[i] = txt.getText();
		}
		Connection result = new Connection(driver, val, getChkSavePassword().isSelected(), getTxtUser().getText(), new String(getTxtPassword().getPassword()));
		return result;
	}

	protected void refreshURL() {
		Connection connection = download();
		lblURL.setText(connection.getUrl());
	}

	public void setVisible(boolean b) {
		if (b)
			U.setLocationRelativeTo(this, null);
		super.setVisible(b);
	}

	/**
	 * This method initializes this
	 *
	 * @return void
	 */
	private void initialize() {
		this.setContentPane(getJContentPane());
		this.setTitle("JLightQueryer");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setBackground(new Color(240, 255, 255));
		pack();
	}

	/**
	 * This method initializes jContentPane
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			GridBagConstraints gridBagConstraints14 = new GridBagConstraints();
			gridBagConstraints14.gridx = 1;
			gridBagConstraints14.ipady = 110;
			gridBagConstraints14.gridheight = 2;
			gridBagConstraints14.weighty = 1.0D;
			gridBagConstraints14.fill = GridBagConstraints.BOTH;
			gridBagConstraints14.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints14.weightx = 1.0D;
			gridBagConstraints14.gridy = 0;
			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
			gridBagConstraints13.gridx = 0;
			gridBagConstraints13.ipady = 76;
			gridBagConstraints13.fill = GridBagConstraints.BOTH;
			gridBagConstraints13.weighty = 1.0D;
			gridBagConstraints13.gridy = 1;
			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
			gridBagConstraints12.gridx = 0;
			gridBagConstraints12.gridy = 0;
			lblImage = new JLabel();
			lblImage.setIcon(new ImageIcon(getClass().getResource("/it/bit/jlightqueryer/images/Start.jpg")));
			jContentPane = new JPanel();
			jContentPane.setLayout(new GridBagLayout());
			jContentPane.setBackground(new Color(240, 255, 255));
			jContentPane.add(lblImage, gridBagConstraints12);
			jContentPane.add(getPanConnection(), gridBagConstraints13);
			jContentPane.add(getPanRecent(), gridBagConstraints14);
		}
		return jContentPane;
	}

	/**
	 * This method initializes panConnection
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getPanConnection() {
		if (panConnection == null) {
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.gridx = 0;
			gridBagConstraints2.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints2.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints2.gridy = 2;
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints1.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints1.gridy = 1;
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints.gridx = 0;
			gridBagConstraints.gridy = 0;
			gridBagConstraints.insets = new Insets(5, 5, 0, 5);
			gridBagConstraints.weightx = 1.0;
			panConnection = new JPanel();
			panConnection.setLayout(new GridBagLayout());
			panConnection.setOpaque(false);
			panConnection.add(getCmbDriver(), gridBagConstraints);
			panConnection.add(getPanVariales(), gridBagConstraints1);
			panConnection.add(getPanConstants(), gridBagConstraints2);
		}
		return panConnection;
	}

	/**
	 * This method initializes panRecent
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getPanRecent() {
		if (panRecent == null) {
			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
			gridBagConstraints11.gridx = 0;
			gridBagConstraints11.weightx = 1.0D;
			gridBagConstraints11.gridy = 0;
			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
			gridBagConstraints10.gridx = 1;
			gridBagConstraints10.fill = GridBagConstraints.BOTH;
			gridBagConstraints10.gridy = 0;
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.fill = GridBagConstraints.BOTH;
			gridBagConstraints3.weighty = 1.0;
			gridBagConstraints3.gridy = 1;
			gridBagConstraints3.weightx = 1.0;
			gridBagConstraints3.gridwidth = 2;
			gridBagConstraints3.gridx = 0;
			lblRecent = new JLabel();
			lblRecent.setText("Recent connections");
			panRecent = new JPanel();
			panRecent.setLayout(new GridBagLayout());
			panRecent.setOpaque(false);
			panRecent.add(lblRecent, gridBagConstraints11);
			panRecent.add(getSpnRecent(), gridBagConstraints3);
			panRecent.add(getBtnAdd(), gridBagConstraints10);
		}
		return panRecent;
	}

	/**
	 * This method initializes cmbDriver
	 *
	 * @return javax.swing.JComboBox
	 */
	private JComboBox getCmbDriver() {
		if (cmbDriver == null) {
			cmbDriver = new JComboBox();
			cmbDriver.addItemListener(new java.awt.event.ItemListener() {
				public void itemStateChanged(java.awt.event.ItemEvent e) {
					if (e.getStateChange()==ItemEvent.SELECTED) {
						upload((Driver) cmbDriver.getSelectedItem());
					}
				}
			});
		}
		return cmbDriver;
	}

	/**
	 * This method initializes panVariales
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getPanVariales() {
		if (panVariales == null) {
			panVariales = new JPanel();
			panVariales.setLayout(new GridBagLayout());
			panVariales.setOpaque(false);
		}
		return panVariales;
	}

	/**
	 * This method initializes panConstants
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getPanConstants() {
		if (panConstants == null) {
			GridBagConstraints gridBagConstraints15 = new GridBagConstraints();
			gridBagConstraints15.gridx = 1;
			gridBagConstraints15.anchor = GridBagConstraints.WEST;
			gridBagConstraints15.insets = new Insets(5, 5, 0, 0);
			gridBagConstraints15.ipady = -10;
			gridBagConstraints15.gridy = 2;
			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
			gridBagConstraints4.gridx = 0;
			gridBagConstraints4.gridwidth = 2;
			gridBagConstraints4.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints4.insets = new Insets(5, 0, 0, 0);
			gridBagConstraints4.gridy = 4;
			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
			gridBagConstraints9.gridy = 3;
			gridBagConstraints9.gridwidth = 2;
			gridBagConstraints9.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints9.insets = new Insets(10, 0, 0, 0);
			gridBagConstraints9.gridx = 0;
			lblURL = new JLabel();
			lblURL.setPreferredSize(new Dimension(200, 14));
			lblURL.setFont(new Font("Dialog", Font.PLAIN, 10));
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints8.gridy = 1;
			gridBagConstraints8.weightx = 1.0;
			gridBagConstraints8.insets = new Insets(5, 5, 0, 0);
			gridBagConstraints8.gridx = 1;
			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
			gridBagConstraints7.gridy = 1;
			gridBagConstraints7.anchor = GridBagConstraints.EAST;
			gridBagConstraints7.insets = new Insets(5, 0, 0, 0);
			gridBagConstraints7.gridx = 0;
			lblPassword = new JLabel();
			lblPassword.setText("Password");
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints6.gridx = 1;
			gridBagConstraints6.gridy = 0;
			gridBagConstraints6.insets = new Insets(0, 5, 0, 0);
			gridBagConstraints6.weightx = 1.0;
			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
			gridBagConstraints5.anchor = GridBagConstraints.EAST;
			gridBagConstraints5.gridy = 0;
			gridBagConstraints5.gridx = 0;
			lblUser = new JLabel();
			lblUser.setText("User");
			panConstants = new JPanel();
			panConstants.setLayout(new GridBagLayout());
			panConstants.setOpaque(false);
			panConstants.add(lblUser, gridBagConstraints5);
			panConstants.add(getTxtUser(), gridBagConstraints6);
			panConstants.add(lblPassword, gridBagConstraints7);
			panConstants.add(getTxtPassword(), gridBagConstraints8);
			panConstants.add(lblURL, gridBagConstraints9);
			panConstants.add(getBtnConnect(), gridBagConstraints4);
			panConstants.add(getChkSavePassword(), gridBagConstraints15);
		}
		return panConstants;
	}

	/**
	 * This method initializes txtUser
	 *
	 * @return javax.swing.JTextField
	 */
	private JTextField getTxtUser() {
		if (txtUser == null) {
			txtUser = new JTextField();
			txtUser.setColumns(10);
		}
		return txtUser;
	}

	/**
	 * This method initializes txtPassword
	 *
	 * @return javax.swing.JPasswordField
	 */
	private JPasswordField getTxtPassword() {
		if (txtPassword == null) {
			txtPassword = new JPasswordField();
			txtPassword.setFont(new Font("Dialog", Font.PLAIN, 10));
		}
		return txtPassword;
	}

	/**
	 * This method initializes spnRecent
	 *
	 * @return javax.swing.JScrollPane
	 */
	private JScrollPane getSpnRecent() {
		if (spnRecent == null) {
			spnRecent = new JScrollPane();
			spnRecent.setPreferredSize(new Dimension(200, 100));
			spnRecent.setViewportView(getTableRecent());
		}
		return spnRecent;
	}

	/**
	 * This method initializes listSelectionModelRecent
	 *
	 * @return javax.swing.DefaultListSelectionModel
	 */
	private DefaultListSelectionModel getListSelectionModelRecent() {
		if (listSelectionModelRecent == null) {
			listSelectionModelRecent = new DefaultListSelectionModel();
			listSelectionModelRecent
					.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
						public void valueChanged(javax.swing.event.ListSelectionEvent e) {
							selectC();
						}
					});
		}
		return listSelectionModelRecent;
	}

	/**
	 * This method initializes btnConnect
	 *
	 * @return javax.swing.JButton
	 */
	private JButton getBtnConnect() {
		if (btnConnect == null) {
			btnConnect = new JButton();
			btnConnect.setText("Connect");
			btnConnect.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					connectC();
				}
			});
		}
		return btnConnect;
	}

	/**
	 * This method initializes tableRecent
	 *
	 * @return javax.swing.JTable
	 */
	private JTable getTableRecent() {
		if (tableRecent == null) {
			tableRecent = new JTable();
			tableRecent.setFont(new Font("Dialog", Font.PLAIN, 10));
			tableRecent.setRowHeight(12);
			tableRecent.setTableHeader(null);
			tableRecent.setSelectionModel(getListSelectionModelRecent());
			tableRecent.setModel(new AbstractTableModel() {
				private static final long serialVersionUID = -8319733009070578883L;
				public int getColumnCount() {
					return 2;
				}
				public int getRowCount() {
					return connections.size();
				}
				public Object getValueAt(int rowIndex, int columnIndex) {
					Object[] o = (getConnection(getRecentRow(rowIndex))).toTableRow();
					return o[columnIndex];
				}
			});
			tableRecent.addMouseListener(new java.awt.event.MouseAdapter() {
				public void mouseClicked(java.awt.event.MouseEvent e) {
					if (e.getClickCount()==2) {
						connectC();
					}
				}
			});
		}
		return tableRecent;
	}

	/**
	 * This method initializes btnAdd
	 *
	 * @return javax.swing.JButton
	 */
	private JButton getBtnAdd() {
		if (btnAdd == null) {
			btnAdd = new JButton();
			btnAdd.setText("New");
			btnAdd.setMargin(new Insets(1, 1, 1, 1));
			btnAdd.setPreferredSize(new Dimension(33, 16));
			btnAdd.setFont(new Font("Dialog", Font.PLAIN, 10));
			btnAdd.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					newC();
				}
			});
		}
		return btnAdd;
	}

	/**
	 * This method initializes chkSavePassword
	 *
	 * @return javax.swing.JCheckBox
	 */
	private JCheckBox getChkSavePassword() {
		if (chkSavePassword == null) {
			chkSavePassword = new JCheckBox();
			chkSavePassword.setOpaque(false);
			chkSavePassword.setSelected(true);
			chkSavePassword.setText("Save password");
		}
		return chkSavePassword;
	}


}  //  @jve:decl-index=0:visual-constraint="10,10"
